import { computed, unref, ref, nextTick, watch } from 'vue'
import { getViewportOffset } from 'utils/domUtils'
import { isBoolean } from 'utils/validate'
import { useWindowSizeFn } from './useWindowSizeFn'
import { onMountedOrActivated } from './onMountedOrActivated'
import { useDebounceFn } from '@vueuse/core' // vueuse中的节流方法 useDebounceFn

export function useTableScroll(propsRef, tableElRef, columnsRef, rowSelectionRef) {
  const tableHeightRef = ref(null)

  // Greater than animation time 280
  const debounceRedoHeight = useDebounceFn(redoHeight, 100)

  const getCanResize = computed(() => {
    const { canResize, scroll } = unref(propsRef)
    return canResize && !(scroll || {}).y
  })

  watch(
    () => [unref(getCanResize), unref(propsRef.data)?.length],
    () => {
      debounceRedoHeight()
    },
    {
      flush: 'post'
    }
  )

  function redoHeight() {
    nextTick(() => {
      calcTableHeight()
    })
  }

  function setHeight(heigh) {
    tableHeightRef.value = heigh
  }

  let bodyEl = null
  let paginationEl = null

  async function calcTableHeight() {
    const { resizeHeightOffset, pagination, maxHeight, minHeight, data } = unref(propsRef)
    const tableData = data
    const table = unref(tableElRef)
    if (!table) return

    const tableEl = table.$el

    if (!tableEl) return

    if (!bodyEl) {
      bodyEl = tableEl.querySelector('.el-table__body')
      if (!bodyEl) return
    }

    const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight

    if (hasScrollBarY) {
      tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.remove('hide-scrollbar-y')
    } else {
      !tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.add('hide-scrollbar-y')
    }

    bodyEl.style.height = 'unset'

    if (!unref(getCanResize) || tableData?.length === 0) return

    await nextTick()

    const headEl = tableEl.querySelector('.el-table__body thead')
    if (!headEl) return

    const { bottomIncludeBody } = getViewportOffset(headEl)

    let paginationHeight = 32
    // 是否有分页
    if (!isBoolean(pagination)) {
      paginationEl = tableEl.querySelector('.pagination__wrap')
      if (paginationEl) {
        const offsetHeight = paginationEl.offsetHeight
        paginationHeight += offsetHeight || 0
      } else {
        paginationHeight += 24
      }
    } else {
      paginationHeight = 0
    }

    let headerHeight = 0
    if (headEl) {
      headerHeight = headEl.offsetHeight
    }

    let height = bottomIncludeBody - (resizeHeightOffset || 0) - paginationHeight - headerHeight
    height = (height < minHeight ? minHeight : height) ?? height
    height = (height > maxHeight ? maxHeight : height) ?? height
    // bodyEl.style.height = `${height}px`
    setHeight(height)
  }

  useWindowSizeFn(calcTableHeight, 280)

  onMountedOrActivated(() => {
    calcTableHeight()
    nextTick(() => {
      debounceRedoHeight()
    })
  })
  const getScrollX = computed(() => {
    let width = 0
    if (unref(rowSelectionRef)) {
      width += 60
    }

    const NORMAL_WIDTH = 120

    const columns = unref(columnsRef).filter((item) => !item.defaultHidden)
    columns.forEach((item) => {
      width += Number.parseInt(item.width) || 0
    })
    const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width'))

    const len = unsetWidthColumns.length
    if (len !== 0) {
      width += len * NORMAL_WIDTH
    }
    const table = unref(tableElRef)
    const tableWidth = table?.$el?.offsetWidth ?? 0
    return tableWidth > width ? '100%' : width
  })

  const getScrollRef = computed(() => {
    const tableHeight = unref(tableHeightRef)
    const { canResize, scroll } = unref(propsRef)
    return {
      x: unref(getScrollX),
      y: canResize ? tableHeight : null,
      scrollToFirstRowOnChange: false,
      ...scroll
    }
  })

  return {
    tableHeightRef,
    getScrollRef,
    redoHeight
  }
}
